package com.alvin.module.redis;

import com.alvin.module.utility.SerializeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @Author: Alvin
 * @Project_name SpringbootTest
 * @Package_name: com.alvin.module.redis
 * @Type_name RabbitMQ
 * @Date: 2017/5/23
 */
public class RedisUtils {
    private static final Logger logger = LoggerFactory.getLogger(RedisUtils.class);

    //Redis服务器IP
    private static final String ADDRESS = "10.211.55.8";
    //Redis的端口号
    private static final int PORT = 6379;
    //访问密码
    private static final String AUTH = "sparkant@123";
    //可用连接实例的最大数目，默认值为8；
    //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
    private static final int MAX_ACTIVE = 1024;
    //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值也是8
    private static final int MAX_IDLE = 200;
    //等待可用连接的最大时间，单位毫秒，默认值为-1，表示永不超时。如果超过等待时间，则直接抛出JedisConnectionException；
    private static final int MAX_WAIT = 30000;
    private static final int TIME_OUT = 30000;
    //在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
    private static final boolean TEST_ON_BORROW = true;

    private static JedisPool jedisPool = null;

    /**
     * 初始化Redis连接池
     */
    static {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            //config.setMaxActive(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWaitMillis(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);
            jedisPool = new JedisPool(config, ADDRESS, PORT, TIME_OUT, AUTH);
        } catch (Exception e) {
            logger.info("context", e);
        }
    }

    /**
     * 获取Jedis实列
     *
     * @return
     */
    public synchronized static Jedis getJedis() {
        Jedis resouce = null;
        try {
            if (jedisPool != null) {
                resouce = jedisPool.getResource();
            }
        } catch (Exception e) {
            logger.info("context", e);
        }
        return resouce;
    }

    /**
     * 释放jedis资源
     */
    public static void releaseJedis(final Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    /**
     * redis保存字符串
     *
     * @param key
     * @param value
     */
    public static void setString(String key, String value) {
        Jedis jedis = getJedis();
        try {
            jedis.set(key, value);
        } catch (Exception e) {
            logger.error("error", e);
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * redis保存字符串 且有效时间
     *
     * @param key
     * @param seconds 分钟
     * @param value
     */
    public static void setString(String key, int seconds, String value) {
        Jedis jedis = getJedis();
        try {
            jedis.setex(key, seconds * 60, value);
        } catch (Exception e) {
            logger.error("error", e);
        } finally {
            releaseJedis(jedis);
        }

    }

    /**
     * 根据key获取redis保存信息
     *
     * @param key
     * @return
     */
    public static String getString(String key) {
        Jedis jedis = getJedis();
        String result = null;
        try {
            result = getJedis().get(key);
        } catch (Exception e) {
            logger.error("error", e);
        } finally {
            releaseJedis(jedis);
        }
        return result;
    }

    /**
     * 删除某键值
     *
     * @param key
     */
    public static void deleteKey(String key) {
        Jedis jedis = getJedis();
        try {
            getJedis().del(key);
        } catch (Exception e) {
            logger.error("error", e);
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * 根据内容拼接
     *
     * @param key
     * @param value
     */
    public static void appendString(String key, String value) {
        Jedis jedis = getJedis();
        try {
            getJedis().append(key, value);
        } catch (Exception e) {
            logger.error("error", e);
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * 保存对象
     *
     * @param key
     * @param value
     */
    public static void setObject(String key, Object value) {
        Jedis jedis = getJedis();
        try {
            getJedis().set(key.getBytes(), SerializeUtils.serialize(value));
        } catch (Exception e) {
            logger.error("error", e);
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * 保存对象,带无效时间
     *
     * @param key
     * @param seconds 分钟
     * @param value
     */
    public static void setObject(String key, int seconds, Object value) {
        Jedis jedis = getJedis();
        try {
            getJedis().setex(key.getBytes(), seconds * 60, SerializeUtils.serialize(value));
        } catch (Exception e) {
            logger.error("error", e);
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * 获取保存对象
     *
     * @param key
     * @return
     */
    public static Object getObject(String key) {
        Jedis jedis = getJedis();
        try {
            return SerializeUtils.unSerialize(getJedis().get(key.getBytes()));
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * 存储REDIS队列 顺序存储
     *
     * @param key   键值
     * @param value 对象
     */
    public static void lpush(String key, Object value) {
        Jedis jedis = getJedis();
        try {
            jedis.lpush(key.getBytes(), SerializeUtils.serialize(value));
        } catch (Exception e) {
            logger.error("error", e);
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * 获取队列里面第一个对象
     *
     * @param key
     * @return
     */
    public static Object rpop(String key) {
        Jedis jedis = getJedis();
        try {
            return SerializeUtils.unSerialize(jedis.rpop(key.getBytes()));
        } finally {
            releaseJedis(jedis);
        }
    }


    /**
     * 存储REDIS队列 反向存储
     *
     * @param key   键值
     * @param value 对象
     */
    public static void rpush(String key, Object value) {
        Jedis jedis = getJedis();
        try {
            jedis.rpush(key.getBytes(), SerializeUtils.serialize(value));
        } catch (Exception e) {
            logger.error("error", e);
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * 获取队列里面最后一个对象
     *
     * @param key
     * @return
     */
    public static Object lpop(String key) {
        Jedis jedis = getJedis();
        try {
            return SerializeUtils.unSerialize(jedis.lpop(key.getBytes()));
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * 检查key是否存在
     *
     * @param key
     * @return
     */
    public static boolean existsKey(String key) {
        Jedis jedis = getJedis();
        try {
            return getJedis().exists(key);
        } finally {
            releaseJedis(jedis);
        }
    }

    public static void main(String[] args) {
//        User user = new User();
//        user.setUserName("name1");
//        user.setId(18);
//        RedisUtils.setObject("user", user);
//        user = (User)RedisUtils.getObject("user");
//        System.out.println("userid:" + user.getId());
//        System.out.println(getJedis().exists("user"));
//        RedisUtils.deleteKey("user");
//        System.out.println(getJedis().exists("user"));
    }
}
